"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 系统内部使用工具
Case Name   : 同一主机build该主机相同同端口级联备
Create At   : 2022/06/08
Owner       : opentestcase023
Description :
    1.备1节点初始化数据库
    1.备1节点配置guc参数
    3.级联备配置guc参数
    4.build相同端口级联备
    5.清理环境
Expect      :
    1.数据库初始化成功
    2.guc参数配置成功
    3.guc参数配置成功
    4.build失败
    5.环境清理成功
History     :
"""
import os
import unittest

from yat.test import Node
from yat.test import macro

from testcase.utils.Common import Common
from testcase.utils.Common import CommonSH
from testcase.utils.Logger import Logger

primary_sh = CommonSH('PrimaryDbUser')


@unittest.skipIf(3 != primary_sh.get_node_num(), '非1+2环境不执行')
class Tools(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.common = Common()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.primary_node = Node('PrimaryDbUser')
        self.standby1_root_node = Node('Standby1Root')
        self.standby1_node = Node('Standby1DbUser')
        self.standby2_root_node = Node('Standby2Root')
        self.standby2_node = Node('Standby2DbUser')
        self.pri_host = self.primary_node.ssh_host
        self.sta1_host = self.standby1_node.ssh_host
        self.port = self.standby1_node.db_port
        self.dn_path = os.path.join(os.path.dirname(macro.DB_INSTANCE_PATH),
                                    'dn_path')
        self.conf_path = os.path.join(macro.DB_INSTANCE_PATH,
                                      macro.DB_PG_CONFIG_NAME)

    def test_gs_ctl(self):
        text = '----step1:在备1执行init数据库 expect:成功----'
        self.log.info(text)
        mkdir_cmd = f'rm -rf {self.dn_path};' \
                    f'mkdir {self.dn_path};ls {os.path.dirname(self.dn_path)}'
        self.log.info(mkdir_cmd)
        dir_res = self.common.get_sh_result(self.standby1_node, mkdir_cmd)
        self.assertIn('dn_path', dir_res, '文件夹创建失败')

        init_cmd = f'source {macro.DB_ENV_PATH};' \
                   f'gs_initdb {self.dn_path} -w"{macro.COMMON_PASSWD}" ' \
                   f'--nodename=single'
        self.log.info(init_cmd)
        init_res = self.common.get_sh_result(self.standby1_node, init_cmd)
        self.assertIn('Success', init_res, 'init失败')

        text = '----step2:在备1配置guc参数 expect:成功----'
        self.log.info(text)
        text = '----查看主机名----'
        self.log.info(text)
        global sta1_nodename
        sta1_nodename = self.common.get_sh_result(self.standby1_root_node,
                                                  "uname -n")
        self.assertIsNotNone(sta1_nodename, '执行失败:' + text)

        local_port = int(self.port) + 1
        localheartbeatport = int(self.port) + 5
        localservice = int(self.port) + 4
        guc_cmd = f'source {macro.DB_ENV_PATH};' \
                  f'gs_guc reload -D {macro.DB_INSTANCE_PATH} ' \
                  f'-N {sta1_nodename} -c ' \
                  f'"replconninfo3 = \'localhost={self.sta1_host} ' \
                  f'localport={local_port} ' \
                  f'localheartbeatport={localheartbeatport} ' \
                  f'localservice={localservice} ' \
                  f'remotehost={self.sta1_host} ' \
                  f'remoteport={local_port} ' \
                  f'remoteheartbeatport={localheartbeatport} ' \
                  f'remoteservice={localservice}\'"'
        self.log.info(guc_cmd)
        guc_res = self.common.get_sh_result(self.standby1_node, guc_cmd)
        self.assertIn('Success to perform gs_guc', guc_res, 'guc设置失败')

        text = '----step3:在级联备配置guc参数 expect:成功----'
        self.log.info(text)
        az_cmd = f'cat {self.conf_path} | grep AZ'
        self.log.info(az_cmd)
        available_zone = self.common.get_sh_result(self.standby1_node,
                                                   az_cmd).split('\'')[-2]
        guc_cmd1 = f'source {macro.DB_ENV_PATH};' \
                   f'gs_guc set -D {self.dn_path} ' \
                   f'-N {sta1_nodename} -c ' \
                   f'"replconninfo1 = \'localhost={self.sta1_host} ' \
                   f'localport={local_port} ' \
                   f'localheartbeatport={localheartbeatport} ' \
                   f'localservice={localservice} ' \
                   f'remotehost={self.sta1_host} ' \
                   f'remoteport={local_port} ' \
                   f'remoteheartbeatport={localheartbeatport} ' \
                   f'remoteservice={localservice}\'"'
        self.log.info(guc_cmd1)
        guc_res1 = self.common.get_sh_result(self.standby1_node, guc_cmd1)
        self.assertIn('Success to perform gs_guc', guc_res1, 'guc设置失败')

        guc_cmd2 = f'source {macro.DB_ENV_PATH};' \
                   f'gs_guc set -D {self.dn_path} -c ' \
                   f'"listen_addresses=\'localhost,{self.sta1_host}\'"'
        self.log.info(guc_cmd2)
        guc_res2 = self.common.get_sh_result(self.standby1_node, guc_cmd2)
        self.assertIn('Success to perform gs_guc', guc_res2, 'guc设置失败')

        guc_cmd3 = f'source {macro.DB_ENV_PATH};' \
                   f'gs_guc set -D {self.dn_path} -c ' \
                   f'"port=\'{self.port}\'"'
        self.log.info(guc_cmd3)
        guc_res3 = self.common.get_sh_result(self.standby1_node, guc_cmd3)
        self.assertIn('Success to perform gs_guc', guc_res3, 'guc设置失败')

        guc_cmd4 = f'source {macro.DB_ENV_PATH};' \
                   f'gs_guc set -D {self.dn_path} -c ' \
                   f'"local_bind_address=\'{self.sta1_host}\'"'
        self.log.info(guc_cmd4)
        guc_res4 = self.common.get_sh_result(self.standby1_node, guc_cmd4)
        self.assertIn('Success to perform gs_guc', guc_res4, 'guc设置失败')

        guc_cmd5 = f'source {macro.DB_ENV_PATH};' \
                   f'gs_guc set -D {self.dn_path} -c ' \
                   f'"available_zone=\'{available_zone}\'"'
        self.log.info(guc_cmd5)
        guc_res5 = self.common.get_sh_result(self.standby1_node, guc_cmd5)
        self.assertIn('Success to perform gs_guc', guc_res5, 'guc设置失败')

        text = '----step4:build级联备 expect:失败----'
        self.log.info(text)
        build_cmd = f'source {macro.DB_ENV_PATH};' \
                    f'gs_ctl build -b standby_full -D {self.dn_path} ' \
                    f'-C "localhost={self.sta1_host} localport={self.port} ' \
                    f'remotehost={self.sta1_host}  remoteport={self.port}" ' \
                    f'-M casecade_standby'
        self.log.info(build_cmd)
        build_res = self.common.get_sh_result(self.standby1_node, build_cmd)
        check_res = f'FATAL:  could not create ' \
                    f'listen socket for "localhost:{self.port}"'
        self.assertIn(check_res, build_res, '备机build失败')

    def tearDown(self):
        text = "----step5:恢复环境 expect:成功----"
        self.log.info(text)
        del_cmd = f'rm -rf {self.dn_path};ls {os.path.dirname(self.dn_path)}'
        self.log.info(del_cmd)
        del_res = self.common.get_sh_result(self.standby1_root_node, del_cmd)
        guc_cmd = f'source {macro.DB_ENV_PATH};' \
                  f'gs_guc set -D {macro.DB_INSTANCE_PATH} ' \
                  f'-N {sta1_nodename} -c ' \
                  f'"replconninfo3 = \'\'"'
        self.log.info(guc_cmd)
        guc_res = self.common.get_sh_result(self.standby1_node, guc_cmd)
        restart_cmd = f'source {macro.DB_ENV_PATH};' \
                      f'gs_ctl restart -D {macro.DB_INSTANCE_PATH}'
        self.log.info(restart_cmd)
        restart_res = self.common.get_sh_result(self.primary_node, restart_cmd)
        self.assertNotIn('dn_path', del_res, '文件删除失败')
        self.assertIn('Success to perform gs_guc', guc_res, 'guc设置失败')
        self.assertIn('server started', restart_res, '数据库重启失败')
        self.log.info(f'----{os.path.basename(__file__)} finish----')
